package com.cloudbroker.bcs.platform.ltb.middle.aspect;

import com.cloudbroker.bcs.common.auth.AuthUtil;
import com.cloudbroker.bcs.common.constants.LogFields;
import com.cloudbroker.bcs.common.exception.HSBCSErrInfoException;
import com.cloudbroker.bcs.common.util.PrintUtil;
import com.cloudbroker.bcs.common.vo.HSBCSVOBase;
import com.cloudbroker.bcs.platform.ltb.bizapi.constants.HSBCPSErrorCodes;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.base.vo.UserVO;
import com.cloudbroker.bcs.platform.ltb.common.constant.SysContants;
import com.cloudbroker.bcs.platform.ltb.common.constant.type.PlatformType;
import com.cloudbroker.bcs.platform.ltb.common.util.SessionHelper;
import com.cloudbroker.bcs.platform.ltb.middle.context.HSBCPSBizDataContext;
import com.cloudbroker.bcs.platform.ltb.middle.entity.Broker;
import com.cloudbroker.bcs.platform.ltb.middle.entity.Customer;
import com.cloudbroker.bcs.platform.ltb.middle.model.UserCache;
import com.cloudbroker.bcs.platform.ltb.middle.util.UserTokenUtil;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ImportParamsAspect {

    private static final String CLASS_NAME = ImportParamsAspect.class.getName();

    private static final Logger LOGGER = LoggerFactory.getLogger(CLASS_NAME);

    public ImportParamsAspect() {
        PrintUtil.printComponentLoaded(LOGGER, CLASS_NAME);
    }
//
//    public void setRequest(ProceedingJoinPoint joinPoint){
////        Object retVal = null;
////        retVal = joinPoint.proceed();
////
////        Object[] args = joinPoint.getArgs();
////        HttpServletRequest request = null;
////        //通过分析aop监听参数分析出request等信息
////        for (int i = 0; i < args.length; i++) {
////            if (args[i] instanceof HttpServletRequest) {
////                request = (HttpServletRequest) args[i];
////            }
////        }
////        String user_token = request.getParameter("user_token");
////        //
////
////        request.setAttribute("");
//    }
    private String user_token;
    private Object operateObj;

    private void setParams(Object obj){
        UserCache UserCache;
        try {
            Method method=obj.getClass().getMethod("getUser_token");
            user_token = (String)method.invoke(obj);
            if(!StringUtils.isNotBlank(user_token)){
                return;
            }else{
               UserCache = UserTokenUtil.queryUserToken(user_token);
                if(UserCache == null){
                    return;
                }
            }
//            String user_type = UserCache.getUser_type();
//            if (String.valueOf(UserType.CUSTOMER.getVal()).equals(user_type)){
//                obj.getClass().getMethod("setUser", Customer.class).invoke(obj,(Customer)UserCache.getBrokerVO().getUser());
//            }else if (String.valueOf(UserType.LEADER.getVal()).equals(user_type)){
//                obj.getClass().getMethod("setUser", Leader.class).invoke(obj,(Leader)UserCache.getBrokerVO().getUser());
//            }
            if (null != UserCache.getBrokerVO().getUser()){
                obj.getClass().getMethod("setUser", UserVO.class).invoke(obj,UserCache.getBrokerVO().getUser());
            }

            obj.getClass().getMethod("setOp_entrust_way", String.class).invoke(obj,UserCache.getBrokerVO().getOp_entrust_way());
            obj.getClass().getMethod("setOp_station", String.class).invoke(obj,UserCache.getBrokerVO().getOp_station());
            obj.getClass().getMethod("setTerminal_type", String.class).invoke(obj,UserCache.getBrokerVO().getTerminal_type());
            obj.getClass().getMethod("setCompany_id", String.class).invoke(obj,UserCache.getBrokerVO().getCompany_id());
            obj.getClass().getMethod("setSendercomp_id", String.class).invoke(obj,UserCache.getBrokerVO().getSendercomp_id());
            obj.getClass().getMethod("setOp_branch_no", int.class).invoke(obj,UserCache.getBrokerVO().getOp_branch_no());
            obj.getClass().getMethod("setBranch_no", int.class).invoke(obj,UserCache.getBrokerVO().getBranch_no());
            obj.getClass().getMethod("setCompany_id", String.class).invoke(obj,UserCache.getBrokerVO().getCompany_id());
            obj.getClass().getMethod("setSendercomp_id", String.class).invoke(obj,UserCache.getBrokerVO().getSendercomp_id());
        }catch(IllegalAccessException e){
            e.printStackTrace();
        }catch(NoSuchMethodException e){
            e.printStackTrace();
        }catch(InvocationTargetException e){
            e.printStackTrace();
        }
    }

    public Object setRequest(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        HttpServletRequest request = null;
        //通过分析aop监听参数分析出request等信息
        for(Object obj : args){
            setParams(obj);
        }


//        request.setAttribute("mobile_tel","18969501000");
//        request.setAttribute("password","123123");
//        request.setAttribute("auth_check_code","8888");
//        request.setAttribute("sendercomp_id","222");
//        request.setAttribute("company_id","123");
//        request.setAttribute("op_entrust_way","1");
//        request.setAttribute("op_station","1");
//        request.setAttribute("terminal_type","1");
        return pjp.proceed();
    }
    
    private void checkAndBindLoginInfo(Object[] args, String[] requiredPermissions, boolean noRefresh) {
        for (Object arg : args) {
            UserCache sessionIdentity = checkSessionPermission((HSBCSVOBase) arg, requiredPermissions,
                    noRefresh);
            bindUserInfo(sessionIdentity);
            break;
        }
    }
    
    private void bindUserInfo(UserCache sessionIdentity) {
        if (SysContants.SESSION_USER_TYPE_CLIENT.equals(sessionIdentity.getUser_type())) {
            // 当前session是client用户
//            bindClientInfo(sessionIdentity.getCustomer(), sessionIdentity.getBroker(),
//                    sessionIdentity.getBrokerId(), sessionIdentity.getClient_id(),
//                    sessionIdentity.getPlatformType());
        }
    }
    
    private void bindClientInfo(Customer customer, Broker broker, Long brokerId, Long clientId, Integer platformType) {
        if (PlatformType.MANAGE.getValue().equals(platformType)) {
            if (broker == null) {
                throw new HSBCSErrInfoException(HSBCPSErrorCodes.NO_PERMISSION);
            }
            HSBCPSBizDataContext.setBroker(broker);
            HSBCPSBizDataContext.setTenantId(broker.getTenant_id());
        } else if (PlatformType.MOBILE.getValue().equals(platformType)) {
            if (customer == null) {
                throw new HSBCSErrInfoException(HSBCPSErrorCodes.NO_PERMISSION);
            }
            HSBCPSBizDataContext.setCustomer(customer);
//            HSBCPSBizDataContext.setTenantId(customer.getTenant_id());
        }
        // 保存用户对象到线程上下文
        HSBCPSBizDataContext.setBrokerId(brokerId);
        HSBCPSBizDataContext.setClientId(clientId);
        //重新加入到在线用户列表缓存
        if (customer != null) {
            SessionHelper.getInstance().addOneToBrokeyOnline(String.valueOf(brokerId),
                    String.valueOf(customer.getCustomer_id()));
        }
    }
    
    private UserCache checkSessionPermission(HSBCSVOBase param, String[] requiredPermissions, boolean noRefresh) {
        
        // 获取携带的access_token
        String access_token = param.getUser_token();
        // 获取会话身份对象
        UserCache identity = SessionHelper.getInstance().fetchSessionIdentityByAccess_token(access_token,
                UserCache.class);
        if (null == identity) {
            // 如果会话身份对象不存在则表示未登录或已超时
            throw new HSBCSErrInfoException(HSBCPSErrorCodes.NOT_LOGGED);
        } else {
            // 先不检查client权限(包括大V和粉丝)
            if (!SysContants.SESSION_USER_TYPE_CLIENT.equals(identity.getUser_type())) {
                // 检查是否拥有需要的权限
                if (!AuthUtil.hasPermission(identity.getPermissions(), requiredPermissions)) {
                    throw new HSBCSErrInfoException(HSBCPSErrorCodes.NO_PERMISSION);
                }
            }
            if (!noRefresh) {
                // 刷新会话，重置超时时间
                SessionHelper.getInstance()
                        .refreshSession(PlatformType.getByValue(String.valueOf(identity.getPlatformType())),
                                access_token, identity);
            }
            // 保存access_token到线程上下文
            HSBCPSBizDataContext.setAccess_token(access_token);
            MDC.put(LogFields.ACCESS_TOKEN, access_token);
            // 注意，这里没做clear
            // 当前是放在com.cloudbroker.bcs.common.aspect.LogAspect.log(ProceedingJoinPoint)中clear
        }
        return identity;
    }
    
    //    private void checkAndBindClientInfo(ClientIdParam param, String[] requiredPermissions) {
    //        // 先检查session登录与权限
    //        SessionIdentity sessionIdentity = checkSessionPermission(param, requiredPermissions);
    //        // 如果当前session是client用户，检查参数的client并绑定到线程上
    //        if (SysContants.SESSION_USER_TYPE_CLIENT.equals(sessionIdentity.getUser_type())) {
    //            Long clientId = param.getClient_id();
    //            // 查找客户对象，不存在则抛异常
    //            ClientProfile client = clientProfileService.get(clientId, true);
    //            // 获取session上的用户
    //            String userId = String.valueOf(sessionIdentity.getCustomerId());
    //            // 检查session的user和参数的client是否是同一个
    //            if (!String.valueOf(clientId).equals(userId)) {
    //                LOGGER.error("session user(client) '" + userId + "' cannot operate param client: " + clientId);
    //                throw new HSBCSErrInfoException(HSBCPSErrorCodes.NO_PERMISSION);
    //            }
    //            // 保存客户对象到线程上下文
    //            HSBCPSBizDataContext.setClientProfile(client);
    //        }
    //    }
    
    private void clearBinding() {
        HSBCPSBizDataContext.removeClientProfile();
        HSBCPSBizDataContext.removeAccess_token();
    }
    
}
